import { createContext, useState, Children, FunctionComponentElement, cloneElement } from 'react';
import classnames from 'classnames';
import { MenuItemProps } from './menu-item';
type MenuMode = 'horizontal' | 'vertical';
type SelectCallback = (selectedIndex: string) => void;
export interface MenuProps {
    defaultIndex?: string;
    className?: string;
    mode?: MenuMode;
    style?: React.CSSProperties;
    onSelect?: SelectCallback;
    children?: React.ReactNode;
    defaultOpenSubMenu?: string[];
}

interface IMenuContext {
    index: string;
    onSelect?: SelectCallback;
    mode?: MenuMode;
    defaultOpenSubMenu?: string[];
}
export const MenuContext = createContext<IMenuContext>({ index: '0' });

const Menu = (props: MenuProps) => {
    const { className, mode, style, defaultIndex, children, onSelect, defaultOpenSubMenu = [] } = props;
    const [currentActiveIndex, setActiveIndex] = useState(defaultIndex);

    const classes = classnames('f-menu', className, {
        'f-menu-vertical': mode === 'vertical',
        'f-menu-horizontal': mode === 'horizontal'
    });
    const handleClick = (index: string) => {
        setActiveIndex(index);
        onSelect && onSelect(index);
    };

    // 透传上下文对象
    const passedContext: IMenuContext = {
        index: currentActiveIndex ? currentActiveIndex : '0',
        onSelect: handleClick,
        mode,
        defaultOpenSubMenu
    };

    const renderChildren = () => {
        return Children.map(children, (child, index) => {
            const childElement = child as FunctionComponentElement<MenuItemProps>;

            const displayName = childElement.type.displayName;

            if (displayName === 'MenuItem' || displayName === 'SubMenu') {
                return cloneElement(childElement, { index: index.toString() });
            }
            console.error('please render MenuItem component');
        });
    };

    return (
        <ul className={classes} style={style} data-testid='test-menu'>
            <MenuContext.Provider value={passedContext}>
                {renderChildren()}
            </MenuContext.Provider>
        </ul>
    );
};

export default Menu;